import json

from flask import request
from injector import inject
from dataclasses import dataclass

from src.pkg import validate_error_json, success_json, success_message
from src.schema import SubExercisesSchema, AnswersSchema,ExercisesSchema
from src.schema.exercoses_schema import QuestionSchema, ExitSchema, TryExercisesSchema, QuestionSchemaSign, \
    ExercisesSchemaSelect, ExercisesSignSchema, CateGorySchema, CateGorySchemaRsp, AnswersSchemaRsp, ErrorReplaySchema, \
    CountSchema, ScoreSchema, AnswerErrorSchemRsp, ErrorListSchema, UploadUrlSchema, AudioSchema, UserCategory, \
    AnswersUserSchemaRsp, ExercisesSchemaUserSelect, ExercisesUserSchema, ExercisesUserSignSchema, \
    TryUserExercisesSchema, CategoryScoresSchema, GetSourcesSchema, CountSourcesSchemaRsp, CreeateCategorySchema, \
    DeleteByIdMains
from src.service import ExercisesService
from src.pkg.pageinator import PageModel, PaginatorReq





@inject
@dataclass
class ExercisesHandler:
    exercises_service: ExercisesService

    def select_sub(self):
        req = SubExercisesSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.select_sub(10, int(req.category_id.data))
        return success_json(data)

    def answer(self):
        req = AnswersSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.answer(req.question.data, req.answer.data, req.user_answer.data,
                                             req.answer_id.data, req.exercise_id.data,req.category_id.data,req.branch_id.data)
        resp = AnswersSchemaRsp()
        return success_json(resp.dump(data))
    def user_answer(self):
        req = AnswersSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.answer_user(req.question.data, req.answer.data, req.user_answer.data,
                                             req.answer_id.data, req.exercise_id.data,req.category_id.data,req.branch_id.data)
        resp = AnswersUserSchemaRsp()
        return success_json(resp.dump(data))
    def add_all(self):
        return self.exercises_service.add_all()

    def get_question(self):
        req = QuestionSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.get_question(req.category_id.data, req.branch_id.data)
        resp = ExercisesSchema()
        return success_json(resp.dump(data))
    def get_user_question(self):
        req = QuestionSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.get_user_question(req.category_id.data, req.branch_id.data)
        resp = ExercisesUserSchema()
        return success_json(resp.dump(data))
    def error_list(self):
        req = ErrorListSchema(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data_list, pageinator = self.exercises_service.error_list(req,req.status.data, req.category_id.data, req.exercises_name.data)
        resp = AnswersSchemaRsp()
        return success_json(PageModel(list=resp.dump(data_list, many=True), paginator=pageinator))
    def getCategoryList(self):
        data = self.exercises_service.getCategoryList()
        resp = CateGorySchemaRsp()
        return success_json(resp.dump(data,many=True))

    def get_week_success_task(self):
        data = self.exercises_service.get_week_success_task()
        return success_json(data)

    def get_week_user_success_task(self):
        data = self.exercises_service.get_week_user_success_task()
        return success_json(data)
    def get_moth_count(self):
        data = self.exercises_service.get_moth_count()
        return success_json(data)
    def today(self):
        data = self.exercises_service.today()
        return success_json(data)
    def study_days(self):
        data = self.exercises_service.study_days()
        return success_json(data)
    def get_score(self):
        req = ScoreSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        return success_json(self.exercises_service.get_score(req.branch_id.data))
    def end(self):
        req= ScoreSchema(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.end(req.branch_id.data)
        resp = AnswerErrorSchemRsp()
        print(resp.dump(data,many=True))
        return success_json(resp.dump(data,many=True))
    def getTimeScore(self):
        req = ScoreSchema(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        score,time = self.exercises_service.getTimeScore(req.branch_id.data)
        return success_json({"score":score,"duration":time})

    def answer_sum(self):
        data = self.exercises_service.answer_sum()
        return success_json(data)
    def sum_success_rate(self):
        data = self.exercises_service.sum_success_rate()
        return success_json(data)
    def error_replay(self):
        req = ErrorReplaySchema(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.error_replay(req.branch_id.data)
        resp = AnswersSchemaRsp()
        return success_json(resp.dump(data,many=True))
    def error_user_replay(self):
        req = ErrorReplaySchema(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.error_user_replay(req.branch_id.data)
        resp = AnswersSchemaRsp()
        return success_json(resp.dump(data,many=True))
    def exit(self):
        req = ExitSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        self.exercises_service.exit(req.branch_id.data, req.exercise_id.data)
        return success_message()

    def get_random_categories(self):
        return self.exercises_service.get_random_categories()

    def try_gen(self):
        req = TryExercisesSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.try_gen(req.exercise_id.data,req.category_id.data)
        return success_json(data)
    def sucees_list(self):
        req = PaginatorReq(request.args)
        print(req.current_page.data)
        if not req.validate():
            return validate_error_json(req.errors)
        data_list, pageinator = self.exercises_service.sucees_list(req)
        resp = ExercisesSchemaSelect()
        return success_json(PageModel(list=resp.dump(data_list, many=True), paginator=pageinator))
    def del_fil_user_list(self):
        req = DeleteByIdMains(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        self.exercises_service.del_fil_user_list(req.id.data)
        return success_message()

    def sucees_user_list(self):
        req = PaginatorReq(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data_list, pageinator = self.exercises_service.sucees_user_list(req)
        resp = ExercisesSchemaUserSelect()
        return success_json(PageModel(list=resp.dump(data_list, many=True), paginator=pageinator))


    def getScoreSum(self):
        data = self.exercises_service.getScoreSum()
        return success_json(data)
    def get_question_sign(self):
        req = QuestionSchemaSign()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.get_question_sign(req.exercise_id.data)
        resp = ExercisesSignSchema()
        print(data)
        return success_json(resp.dump(data))

    def get_user_question_sign(self):
        req = QuestionSchemaSign()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.get_question_user_sign(req.exercise_id.data)
        resp = ExercisesUserSignSchema()
        return success_json(resp.dump(data))
    def get_audio_url(self):
        req = UploadUrlSchema(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.get_audio_url(req.exercise_id.data)
        return success_json(data)
    def create_category(self):
        req = CateGorySchema()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.create_category(req.question.data)
        resp = CateGorySchemaRsp()
        return success_json(resp.dump(data,many=True))
    def del_fil_list(self):
        req = DeleteByIdMains(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        self.exercises_service.del_fil_list(req.id.data)
        return success_message()
    def calculate_percentages_for_user(self):
        data = self.exercises_service.calculate_weekly_category_percentages()
        return success_json(data)
    def get_source_chart(self):
        req = CategoryScoresSchema(request.args)
        data = self.exercises_service.get_category_scores(req.start_date.data,req.end_date.data)

        return success_json(data)
    def success_count(self):
        req = CountSchema(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.success_count(req.branch_id.data)
        return success_json(data)
    def time_view(self):
        req = CountSchema(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.time_view(req.branch_id.data)
        return success_json(data)
    def audio_uploads(self,exercise_id:str):
        req = AudioSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        url = self.exercises_service.audio_uploads(req.file.data,exercise_id)
        return success_json(url)
    def chat_audio_upload(self):
        req = AudioSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        url = self.exercises_service.chat_audio_upload(req.file.data)
        return success_json(url)
    def user_category(self):
        req = UserCategory()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.user_category(req.source.data,req.category_id.data)
        return success_json()
    def fil_list(self):
        req = PaginatorReq(request.args)

        if not req.validate():
            return validate_error_json(req.errors)
        data_list, pageinator = self.exercises_service.fil_list(req)
        resp = ExercisesSchemaSelect()
        return success_json(PageModel(list=resp.dump(data_list,many=True), paginator=pageinator))
    def get_category_scores(self):
        req = GetSourcesSchema(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data_list, pageinator = self.exercises_service.get_category_scores(req,req.start_date.data,req.end_date.data)
        resp = CountSourcesSchemaRsp(many=True)
        return success_json(PageModel(list=resp.dump(data_list,many=True), paginator=pageinator))
    def create_category(self):
        req = CreeateCategorySchema()
        if not req.validate():
            return validate_error_json(req.errors)
        lis = self.exercises_service.create_category(req.question.data)
        return success_json(lis)
    def try_user_gen(self):
        req = TryUserExercisesSchema()
        if not req.validate():
            return validate_error_json(req.errors)
        data = self.exercises_service.try_user_gen(req.exercise_id.data, req.category_id.data,req.source.data,req.category_name.data)
        return success_json(data)
    def fil_user_list(self):
        req = PaginatorReq(request.args)
        if not req.validate():
            return validate_error_json(req.errors)
        data_list, pageinator = self.exercises_service.fil_user_list(req)
        resp = ExercisesSchemaUserSelect()
        return success_json(PageModel(list=resp.dump(data_list,many=True), paginator=pageinator))
